package com.relytosoft.mizar.analyze.system.services.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.relytosoft.dubhe.common.core.base.page.PageQuery;
import com.relytosoft.dubhe.common.kafka.producer.KafkaOpMsg;
import com.relytosoft.dubhe.common.kafka.producer.KafkaProducer;
import com.relytosoft.mizar.analyze.base.constant.MediaMqConstants;
import com.relytosoft.mizar.analyze.base.entity.pojo.dto.AyGroupBaseDto;
import com.relytosoft.mizar.analyze.base.entity.pojo.dto.FaceGroupReqDto;
import com.relytosoft.mizar.analyze.system.api.entity.AyGroupBase;
import com.relytosoft.mizar.analyze.system.api.entity.AyPersonGroup;
import com.relytosoft.mizar.analyze.system.api.entity.AyPersonInfo;
import com.relytosoft.mizar.analyze.system.api.entity.AyVehicleGroup;
import com.relytosoft.mizar.analyze.system.api.pojo.vo.AyGroupBaseVo;
import com.relytosoft.mizar.analyze.system.services.mapper.AyGroupBaseMapper;
import com.relytosoft.mizar.analyze.system.services.service.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author lj
 * @date 2022/5/12 11:53
 */
@Service
public class AyGroupBaseServiceImpl extends ServiceImpl<AyGroupBaseMapper, AyGroupBase> implements AyGroupBaseService {

    @Resource
    private KafkaProducer kafkaProducer;

    @Resource
    private AyPersonInfoService ayPersonInfoService;

    @Resource
    private AyPersonGroupService ayPersonGroupService;

    @Resource
    private AyVehicleGroupService ayVehicleGroupService;

    @Resource
    private AyVehicleInfoService ayVehicleInfoService;


    @Override
    public IPage<AyGroupBase> selectAyGroupBasePageList(PageQuery pageQuery, AyGroupBase ayGroupBase) {
        if (StrUtil.isBlank(pageQuery.getOrderByColumn())) {
            pageQuery.setOrderByColumn("id");
            pageQuery.setIsAsc("desc");
        }
        ayGroupBase.setStatus(1);
        return baseMapper.selectPageBaseList(pageQuery.build(), ayGroupBase);
    }

    @Override
    public boolean addAyGroupBase(AyGroupBase ayGroupBase) {
        ayGroupBase.setStatus(1);
        boolean save = this.save(ayGroupBase);
        //为人脸库时需要远程添加
        if (save && ayGroupBase.getType() == 2) {
            sendAddToKafka(ayGroupBase);
            return save;
        }
        return save;
    }

    /**
     * 删除
     *
     * @param list 需要修改的库ID
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public ArrayList<String> updateStatus(List<Integer> list) {
        Integer type = 0;
        if (list.size() > 0) {
            AyGroupBase ayGroupBase = this.getById(list.get(0));
            type = ayGroupBase.getType();
        }
        LambdaQueryWrapper<AyGroupBase> wrapper = new QueryWrapper<AyGroupBase>().lambda();
        wrapper
                .in(list.size() > 0, AyGroupBase::getId, list)
                .eq(AyGroupBase::getStatus, 1);
        //修改所有库状态
        boolean flag = this.update(new AyGroupBase(0), wrapper);

        if (flag && type == 2) {
            //查询库关联所有人信息
            LambdaQueryWrapper<AyPersonGroup> ayPersonGroupWrapper = new QueryWrapper<AyPersonGroup>().lambda();
            ayPersonGroupWrapper
                    .in(list.size() > 0, AyPersonGroup::getGroupId, list);
            List<AyPersonGroup> ayPersonGroupList = ayPersonGroupService.list(ayPersonGroupWrapper);
            if (ayPersonGroupList.size() > 0) {
                Set<Integer> personIds = ayPersonGroupList.stream().map(AyPersonGroup::getPersonId).collect(Collectors.toSet());
                //删除人信息
                for (Integer personId : personIds) {
                    List<Integer> groupIds = ayPersonGroupService.selectByPersonId(personId);
                    groupIds.removeAll(list);
                    if (groupIds.isEmpty()) {
                        List<Integer> arrayList = new ArrayList<>();
                        arrayList.add(personId);
                        ayPersonInfoService.removeAyPersonInfo(arrayList);
                    }
                }
                //删除人库关联信息
                flag = ayPersonGroupService.remove(ayPersonGroupWrapper);
            }
        }


        //查询库关联所有车信息
        if (flag && type == 1) {
            LambdaQueryWrapper<AyVehicleGroup> ayVehicleGroupWrapper = new QueryWrapper<AyVehicleGroup>().lambda();
            ayVehicleGroupWrapper.in(list.size() > 0, AyVehicleGroup::getGroupId, list);
            List<AyVehicleGroup> ayVehicleGroupList = ayVehicleGroupService.list(ayVehicleGroupWrapper);
            if (!ayVehicleGroupList.isEmpty()) {
                Set<Integer> vehicleIds = ayVehicleGroupList.stream().map(AyVehicleGroup::getVehicleId).collect(Collectors.toSet());
                //删除车信息
                for (Integer vehicleId : vehicleIds) {
                    //判断该车是否有被其它库关联
                    List<Integer> groupIds = ayVehicleGroupService.selectByVehicleId(vehicleId);
                    //去除groupIds里面的list
                    groupIds.removeAll(list);
                    if (groupIds.isEmpty()) {
                        List<Integer> arrayList = new ArrayList<>();
                        arrayList.add(vehicleId);
                        ayVehicleInfoService.updateAyVehicleInfoStatus(arrayList);
                    }
                }
                //删除车库关联信息
                flag = ayVehicleGroupService.remove(ayVehicleGroupWrapper);
            }
        }

        //发送消息删除比特大陆人信息
        if (flag && type == 2) {
            //查询需要删除的库
            List<AyGroupBase> ayGroupBases = this.listByIds(list);
            //人脸库时需要删除的三方库ID
            List<String> plateformGroupIds = ayGroupBases
                    .stream()
                    .filter(item -> item.getType() == 2)
                    .map(AyGroupBase::getPlateformGroupId)
                    .collect(Collectors.toList());
            if (plateformGroupIds.size() > 0) {
                return new ArrayList<>(plateformGroupIds);
            }
        }

        if (flag) {
            return new ArrayList<>();
        } else {
            return null;
        }
    }

    @Override
    public boolean updateAyGroupBase(AyGroupBase ayGroupBase) {
        boolean update = this.updateById(ayGroupBase);
        //人脸库时需要远程更新
        if (update && ayGroupBase.getType() == 2) {
            //1. 发送删除的消息
            ArrayList<String> arrayList = new ArrayList<>();
            arrayList.add(ayGroupBase.getPlateformGroupId());
            sendRemoveToKafka(arrayList);
            //2. 发送新增消息
            sendAddToKafka(ayGroupBase);
        }
        return update;
    }


    /**
     * 发送删除消息到kafka
     *
     * @param arrayList 需要删除的库ID集合
     */
    @Override
    public void sendRemoveToKafka(ArrayList<String> arrayList) {
        FaceGroupReqDto faceGroupReqDto = new FaceGroupReqDto();
        faceGroupReqDto.setGroupIds(arrayList);
        //发送需要删除库信息
        KafkaOpMsg kafkaOpMsg = new KafkaOpMsg();
        kafkaOpMsg.setData(JSONObject.toJSONString(faceGroupReqDto));
        kafkaOpMsg.setOpType("deleteGroup");
        kafkaProducer.send(MediaMqConstants.FACE_ANALYZE_PERSON_TOPIC, JSONObject.toJSONString(kafkaOpMsg), true);
    }

    /**
     * 发送新增消息到kafka
     *
     * @param ayGroupBase 参数
     */
    private void sendAddToKafka(AyGroupBase ayGroupBase) {
        FaceGroupReqDto faceGroupReqDto = new FaceGroupReqDto();
        faceGroupReqDto.setGroupId(ayGroupBase.getId());
        faceGroupReqDto.setVolume(ayGroupBase.getVolume());

        KafkaOpMsg kafkaOpMsg = new KafkaOpMsg();
        kafkaOpMsg.setOpType("insertGroup");
        kafkaOpMsg.setData(JSONObject.toJSONString(faceGroupReqDto));
        kafkaProducer.send(MediaMqConstants.FACE_ANALYZE_PERSON_TOPIC, JSONObject.toJSONString(kafkaOpMsg), true);
    }

    /**
     * 查询详情
     *
     * @param id id
     */
    @Override
    public AyGroupBaseVo findById(Integer id) {
        AyGroupBase ayGroupBase = this.getById(id);
        AyGroupBaseVo ayGroupBaseVo = new AyGroupBaseVo();
        BeanUtil.copyProperties(ayGroupBase, ayGroupBaseVo);
        return ayGroupBaseVo;
    }

    @Override
    public List selectGroupWithPersonInfo(Integer groupId, Integer type) {
        if (type == 1) {
            //根据库查询车辆信息
            return this.baseMapper.selectVehicleInfoByGroupId(groupId);
        } else {
            Map<Integer, String> idCard = ayPersonInfoService.selectByValue("idCard");
            Map<Integer, String> education = ayPersonInfoService.selectByValue("education");
            //根据库查询人像信息
            List<AyPersonInfo> ayPersonInfos = this.baseMapper.selectPersonInfoByGroupId(groupId);
            ayPersonInfos.forEach(item -> {
                item.setIdTypeString(idCard.get(item.getIdType()));
                item.setEducationString(education.get(item.getEducation()));
                List<Integer> groupIds = ayPersonGroupService.selectByPersonId(item.getId());
                item.setGroupIds(groupIds);
            });
            return ayPersonInfos;
        }
    }

    @Override
    public Map<String, Integer> selectPlateformAndGroupId(List<String> groupIds) {
        LambdaQueryWrapper<AyGroupBase> wrapper = new QueryWrapper<AyGroupBase>().lambda();
        wrapper.in(AyGroupBase::getPlateformGroupId, groupIds).eq(AyGroupBase::getStatus, 1);
        List<AyGroupBase> ayGroupBaseList = this.list(wrapper);
        return ayGroupBaseList.stream().collect(Collectors.toMap(AyGroupBase::getPlateformGroupId, AyGroupBase::getId));
    }

    @Override
    public List<AyGroupBaseDto> selectGroupByIds(List<Integer> groupIds) {
        LambdaQueryWrapper<AyGroupBase> wrapper = new QueryWrapper<AyGroupBase>().lambda();
        wrapper
                .in(AyGroupBase::getId, groupIds)
                .eq(AyGroupBase::getStatus, 1);
        List<AyGroupBase> ayGroupBaseList = this.list(wrapper);
        List<AyGroupBaseDto> ayGroupBaseDtoList = new ArrayList<>();
        ayGroupBaseList.forEach(item -> {
            AyGroupBaseDto ayGroupBaseDto = new AyGroupBaseDto();
            BeanUtil.copyProperties(item, ayGroupBaseDto);
            ayGroupBaseDtoList.add(ayGroupBaseDto);
        });
        return ayGroupBaseDtoList;
    }
}
